Øvelse 5




del1
i opgaven sharing data between threads skal vi bruge mutexes til at sikre at den delte variabel bliver inkrementeret før variablen bliver udskrevet på skærmen
seleve ideen ved at bruge mutexes er at vi kan sikre at en bestemt sekvens i et stykke kode bliver eksekveret førend vi kan fortsætte med eksekveringen af resten af programmet.

i opgaven sharing a Vector class between threads. bruger vi semephore

Del2

Når vi arbejder med mutex er det vigtigt at vi kun tager låsen for den nødvendige tid. Vi skal derfor forsøge at have låsen taget i så kort tid som muligt.
Når vi arbejder med mutex skal vi initialisere, enten ved dynamisk (pthread_mutex_init()) eller statisk
(PTHREAD_MUTEX_INITIALISZER)

void* write(void* id)
{
    for(int i = 1; i< 101; i++)
    {
        pthread_mutex_lock(&lock);
        if(!vector1.setAndTest(i))
            printf("Error found. Thread: %d, i: %d\n", (int)id, i);
        else
            printf("No Error found. Thread: %d, i: %d\n", (int)id, i);
        pthread_mutex_unlock(&lock);
        usleep(1000000);
    }
 
    pthread_exit(NULL);
}
Når vi er færdige med at bruge låsen er det vigtigt at vi nedlægger låsen igen. Man må aldrig nedlægge en lås der benyttes.

Del 3
Main del er samme som i del 2
i denne opgave oprettes der en kladse til at håndtering af mutexen i constructoren sættes m_owner til lockens værdi, m_owner har til opgave at holde styr på om låsen er taget
#ifndef SCOPEDLOCKER_HPP_
#define SCOPEDLOCKER_HPP_
#include<pthread.h>
 
 
 
 
class ScopedLocker
{
public:
    ScopedLocker(pthread_mutex_t &lock) : m_lock(&lock)
    {
        m_owner = pthread_mutex_lock(m_lock);
    }
 
    ~ScopedLocker()
    {
        if(m_owner != -1)
            pthread_mutex_unlock(m_lock);
    }
 
private:
    pthread_mutex_t *m_lock;
    int m_owner;
 
};
 
 
 
#endif /* SCOPEDLOCKER_HPP_ */
 
Vector classen
Scopedlocker bruges i vectorklassen til at sikre at programmet er låst når vector funktionen setandtest bliver udført.
Det er kun nødvendigt at tage låsen da vi udnytter at vi har en destructor der automatisk slipper låsen når den bliver kaldt. Dermed sikre vi også at vi altid får nedlagt låsen.
class Vector
{
public:
   Vector() : size_(10000)
      {
 
         vector_ = new int[size_];
         set(0);
         //initialicerer mutex
         pthread_mutex_init(&m_lock,NULL);
 
      }
 
   ~Vector()
      {
         delete[] vector_;
         // nedlæger mutexen
         pthread_mutex_destroy(&m_lock);
      }
 
   bool setAndTest(int n)
      {
       ScopedLocker lock(m_lock);
         set(n);
         return test(n);
      }
 
private:
 
 
   void set(int n)
      {
 
           for(unsigned int i=0; i<size_; i++) vector_[i] = n;
 
      }
 
   bool test(int n)
      {
         for(unsigned int i=0; i<size_; i++) if(vector_[i] != n) return false;
         return true;
      }
   pthread_mutex_t m_lock;
 
   int*           vector_;
   unsigned int   size_;
};
 
#endif
Del 4
Når vi compiler til target foregår det på samme måde som ved compiling til Host vi benytter blot en anden compiler. Herefter copiers filen tgt_tgt til Devkit8000 og testes.